/**
 * 音符音乐
 * @author 张勇 41204@qq.com
 * @date 2022-04
 */
 
#pragma once

#include <stdint.h>
#include <stdbool.h>
#include "std_err.h"


/// 音调标识/频率索引
typedef enum enToneIndex {
	TL1, TL1P, TL2, TL2P, TL3, TL4, TL4P, TL5, TL5P, TL6, TL6P, TL7,
	TM1, TM1P, TM2, TM2P, TM3, TM4, TM4P, TM5, TM5P, TM6, TM6P, TM7,
	TH1, TH1P, TH2, TH2P, TH3, TH4, TH4P, TH5, TH5P, TH6, TH6P, TH7,
	TMT /* 休止符 */, 
    TONE_MAX
} ToneIndex;

/// 音调频率索引表(标准频率)
static const uint16_t ToneFreq[] = {
	262,	277,	294,	311,	330,	349,	370,	392,	415,	440,	466,	494,
	523,	554,	587,	622,	659,	698,	740,	784,	831,	880,	932,	988,
	1047,	1109,	1175,	1245,	1319,	1397,	1480,	1568,	1661,	1760,	1865,	1976,
    5000 /* 休止符, 高频 */
};

/// @brief 全拍时长(ms)
/// @detail 在乐谱中，一拍的时长（以毫秒为单位）取决于乐曲的速度（Tempo），即每分钟的拍数（BPM）
/// - 常见流行音乐速度为 120 BPM = 500 ms/拍
#define BEAT_TIME 500

/// 节拍标识/时间索引
typedef enum enBeatIndex {
	B4, B3, B2, B1, B12, B14, B34,
	BEAT_MAX
} BeatIndex;

/// 节拍时间索引表
static const uint16_t BeatTime[] = {
	(BEAT_TIME*4), (BEAT_TIME*3), (BEAT_TIME*2), (BEAT_TIME*1), (BEAT_TIME/2), (BEAT_TIME/4), (BEAT_TIME*3/4)
};

/// 音符
#pragma pack(push, 1)
typedef struct stNote {
	ToneIndex tone:8;	// 音调(频率索引)
	BeatIndex beat:8;	// 节拍(持续时间索引)
} Note;
#pragma pack(pop)

extern const Note notes_music_1234567654321[];
extern const Note notes_music_up2[];
extern const Note notes_music_down2[];
extern const Note notes_music_up3[];
extern const Note notes_music_down3[];
extern const Note notes_music_didi[];
extern const Note notes_music_little_stars[];
extern const Note notes_music_sunlight[];

/// 是否是合法的音节
bool note_validate(const Note *note);
/// 下一个音节
const Note* note_next(const Note *notes);
/// 音节频率(Hz)
static inline uint16_t note_freq_hz(const Note *notes) { return ToneFreq[notes->tone]; }
/// 音节时长(ms)
/// @param speed 播放速度（单位: 1%）
static inline uint16_t note_time_ms(const Note *notes, uint16_t speed) { return BeatTime[notes->beat] * 100U / speed; }
